﻿//----------------------------------------------------------------------------------------------------
// The NodeManager is in charge of creating and fetching info for node types
// - Not to be confused with LevelManager which is in charge of Node Instances.
//----------------------------------------------------------------------------------------------------
package HG.Managers
{
	import HG.GameDataTypes.NodeType;
	
	import HG.Debug;
	
	import HG.Visual.VisualNode;
	
	import HG.GameService;
	import HG.Managers.LevelManager;
	import HG.Managers.PlayerManager;
	
	import HG.Events.PlayerEvent;
	import HG.Events.NodeEvent;
	
	public class NodeManager extends IGameManager
	{
		public static const NODE_ROOT:String = "Root";
		public static const NODE_GOAL:String = "Goal";
		public static const NODE_SERVER:String = "Server";
		public static const NODE_GENERATOR:String = "Generator";
		public static const NODE_DOCUMENT:String = "Document";
		public static const NODE_SENTRY:String = "Sentry";
		
		var m_nodeTypeMap:Array;
		var m_nodeTypeNameArray:Vector.<String>;
		
		var m_levelManager:LevelManager;
		var m_playerManager:PlayerManager;
		
		var m_nodeCaps:Array;
		
		//----------------------------------------------------------------------------------------------------
		public function NodeManager()
		{
			m_nodeTypeMap = new Array();
			m_nodeTypeNameArray = new Vector.<String>;
			
			m_nodeCaps = new Array();
		}
		
		//----------------------------------------------------------------------------------------------------
		public override function Initialize()
		{
			InitNodeTypes();
			
			m_levelManager = GameService.GetInstance().GetLevelManager();
			m_levelManager.addEventListener(NodeEvent.CAPTURE, OnNodeCaptured);
			
			m_playerManager = GameService.GetInstance().GetPlayerManager();
			m_playerManager.addEventListener(PlayerEvent.JOIN, OnPlayerJoined);
			m_playerManager.addEventListener(PlayerEvent.FATE, OnPlayerFate);
		}
		
		//----------------------------------------------------------------------------------------------------
		public override function Shutdown()
		{
			
		}
		
		//----------------------------------------------------------------------------------------------------
		public override function OnTick(DeltaTime:Number)
		{
			
		}
		
		//----------------------------------------------------------------------------------------------------
		private function OnPlayerFate(evt:PlayerEvent)
		{
			if (evt.m_fate != GameRuleManager.FATE_DEFEAT)
				return;
				
			var nodes:Vector.<Number> = m_nodeCaps[evt.m_playerNumber];
			
			var index:Number = 0;
			var listLength:Number = nodes.length;
			
			for (index = 0; index < listLength; ++index)
			{
				var nodeID:Number = nodes[index];
				
				var visNode:VisualNode = m_levelManager.GetVisualNode(nodeID);
				
				visNode.RemoveOcupant(evt.m_playerNumber);
				visNode.ClearPendingActionForPlayer(evt.m_playerNumber);
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		private function OnPlayerJoined(evt:PlayerEvent)
		{
			m_nodeCaps[evt.m_playerNumber] = new Vector.<Number>;
			
			var playerRootNode:Number  = m_playerManager.GetPlayer(evt.m_playerNumber).GetRootNode();
			m_nodeCaps[evt.m_playerNumber].push(playerRootNode);
		}
		
		//----------------------------------------------------------------------------------------------------
		private function OnNodeCaptured(evt:NodeEvent)
		{
			m_nodeCaps[evt.m_capBy].push(evt.m_node.GetID());
		}
		
		//----------------------------------------------------------------------------------------------------
		// In leu of being laoded form disc, declare all node info here.
		//----------------------------------------------------------------------------------------------------
		private function InitNodeTypes()
		{
			// Nothing can be done to root nodes.
			var type:NodeType = AddNodeType(NODE_ROOT);
			
			type = AddNodeType(NODE_GOAL);
			type.AddActionType(ActionManager.ACTION_HACK);
			
			type = AddNodeType(NODE_SERVER);
			type.AddActionType(ActionManager.ACTION_HACK);
			type.AddActionType(ActionManager.ACTION_UNLOCK);
			
			type = AddNodeType(NODE_GENERATOR);
			type.AddActionType(ActionManager.ACTION_HACK);
			
			type = AddNodeType(NODE_DOCUMENT);
			type.AddActionType(ActionManager.ACTION_DOWNLOAD);
			
			type = AddNodeType(NODE_SENTRY);
			type.AddActionType(ActionManager.ACTION_HACK);
		}
		
		//----------------------------------------------------------------------------------------------------
		private function AddNodeType(typeString:String):NodeType
		{
			Debug.ASSERT(!m_nodeTypeMap[typeString], "Attempt to add duplicate node type");
			
			m_nodeTypeNameArray.push(typeString);
			m_nodeTypeMap[typeString] = new NodeType(typeString);
			return m_nodeTypeMap[typeString];
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetNodeTypes():Vector.<String>
		{
			return m_nodeTypeNameArray;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetNodeTypeActions(type:String):Array
		{
			return m_nodeTypeMap[type].GetActionTypes();
		}

	}
}





